#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::endl;
using std::unique_ptr;
using std::shared_ptr;
using std::weak_ptr;
using std::vector;

class Point 
: public std::enable_shared_from_this<Point> 
{
public:
        //...
    Point(int x = 0, int y = 0)
        :_ix(x)
        ,_iy(y){
        std::cout << "构造Point(" << x << "," << y << ") @" << this << std::endl;
    }

    ~Point() {
        std::cout << "析构Point @" << this << std::endl;
    }

    void print() const {
        std::cout << "Point(" << _ix << "," << _iy << ") @" << this << std::endl;
    }

private:
    int _ix;
    int _iy;
};

void unique_ptr_test1(){
    unique_ptr<int> up(new int(10));
    cout << "*up: " << *up << "\n";
    cout << "up.get(): " << up.get() << "\n";
    cout << "==========" << "\n";

    //unique_ptr<int> up2 = up;
    unique_ptr<int> up2 = std::move(up);
    cout << "test 15" << endl;
    // cout << "*up: " << *up << "\n";
    cout << "*up2: " << *up2 << "\n";

    unique_ptr<int> up3(new int(20));
    //up3 = up22;
    up3 = std::move(up2);
    //cout << "*up: " << *up << "\n";
    //cout << "*up2: " << *up2 << "\n";
    cout << "*up3: " << *up3 << "\n";
}

void unique_ptr_test2() {
	vector<unique_ptr<Point>> vec;
    for(int i = 0; i < 10; i++){
        vec.push_back(unique_ptr<Point>(new Point(i, i + 1)));
    }
    //unique_ptr<Point> up4(new Point(10,20));
    //vec.push_back(up4);  //error
    
    //vec.push_back(std::move(up4));  //ok
    //vec.push_back(unique_ptr<Point>(new Point(1,3))); //ok
    
    auto it = vec.begin();
    while(it != vec.end()){
        //cout << (*it)->print() << "\n";
        //cout << ((*it).print()) << "\n";
        (*it)->print();  // 直接调用成员函数
        it++;
    }
    cout << endl;
}

void shared_ptr_test1(){
    shared_ptr<int> sp(new int(10));
    cout << "sp.usecount():" << sp.use_count() << endl;

    shared_ptr<int> sp2 = sp;
    cout << "sp.use_count():" << sp.use_count() << endl;
    cout << "sp2.use_count():" << sp2.use_count() << endl;

    shared_ptr<int> sp3(new int(30));
    sp3 = sp;
    cout << "sp3.use_count():" << sp3.use_count() << endl;
}

void weak_ptr_test1(){
    //weak_ptr<int> wp(new int (10));
    weak_ptr<int> wp;
    if(shared_ptr<int> sp = wp.lock()){
        cout << "*sp:" << *sp << endl;
    }else{
        cout << "wp指向的对象已释放" << endl;
    }

    shared_ptr<int> sp2(new int(10));
    weak_ptr<int> wp2;
    cout << "use_count:" << wp2.use_count() << endl;
    if(auto sp3 = wp2.lock()){
        cout << "*sp3:" << *sp3 << endl;
    }
}

int main()
{
    unique_ptr_test1();
    unique_ptr_test2();
   
    shared_ptr_test1();

    weak_ptr_test1();

    return 0;
}

